/*函数节流*/
export function throttle(fn, interval) {
  var enterTime = 0;//触发的时间
  var gapTime = interval || 300 ;//间隔时间，如果interval不传，则默认300ms
  return function() {
    var context = this;
    var backTime = new Date();//第一次函数return即触发的时间
    if (backTime - enterTime > gapTime) {
      fn.call(context,arguments);
      enterTime = backTime;//赋值给第一次触发的时间，这样就保存了第二次触发的时间
    }
  };
}

/*函数防抖*/
export function debounce(fn, interval) {
  var timer;
  var gapTime = interval || 200;//间隔时间，如果interval不传，则默认1000ms
  return function() {
    clearTimeout(timer);
    var context = this;
    var args = arguments;//保存此处的arguments，因为setTimeout是全局的，arguments不是防抖函数需要的。
    timer = setTimeout(function() {
      fn.call(context,args);
    }, gapTime);
  };
}

/**
 * 用于检查是否是有效的 JSON 格式
 * @description 是否对象
 * @param str
 * @returns {[]}
 */
export function isJSON(str) {
    if (typeof str == "string") {
        try {
            var obj = JSON.parse(str)
            if (typeof obj == "object" && obj) {
                return true
            } else {
                return false
            }
        } catch (e) {
            // console.log('error：' + str + '!!!' + e)
            return false
        }
    }
}

// 用于将 JSON 字符串转换成对象
export function objFieldStrToObj(obj) {
    Object.keys(obj).forEach(key => {
        const item = obj[key];

        // 判断是否是有效的 JSON 字符串
        if (typeof item === 'string' && (isArrayOrObjString(item))) {
            try {
                // 如果是 JSON 字符串，解析它
                obj[key] = JSON.parse(item);
            } catch (e) {
                console.error(`解析字段 "${key}" 时出错:`, e);
            }
        }
    });

    return obj;  // 返回修改后的对象
}

// 用于判断字符串是否是有效的 JSON 数组或对象格式
function isArrayOrObjString(str) {
    try {
        // 尝试解析，如果是数组或对象形式的字符串，则返回 true
        const parsed = JSON.parse(str);
        return typeof parsed === 'object' && parsed !== null;
    } catch (e) {
        return false; // 如果解析失败，返回 false
    }
}

// 将 JSON 字符串转成对象并进行进一步处理
export function JsonParse(str) {
    if (isJSON(str)) {
        const obj = JSON.parse(str);  // 首先解析 JSON 字符串
        return objFieldStrToObj(obj);  // 处理对象中的字段
    }
    return null;  // 如果不是有效的 JSON，返回 null
}


/**
 * 将平面列表转换为树结构
 * @param {Array} list - 平面列表，每个项目包含 id 和 parentId
 * @param {String} idKey - 用于唯一标识每个项目的键名
 * @param {String} parentIdKey - 用于标识父项目的键名
 * @param {String} childrenKey - 用于存储子项目的键名
 * @returns {Array} - 转换后的树结构
 */
export function listToTree(list, idKey = 'id', parentIdKey = 'parentId', childrenKey = 'children') {
  // 创建一个字典来快速查找节点
  const map = {};
  list.forEach(item => {
    map[item[idKey]] = { ...item, [childrenKey]: [] };
  });

  // 构建树结构
  const tree = [];
  list.forEach(item => {
    const { [idKey]: id, [parentIdKey]: parentId } = item;
    if (parentId === null || parentId === undefined || parentId == '0') {
      // 没有父节点的项目为根节点
      tree.push(map[id]);
    } else {
      // 有父节点的项目，添加到其父节点的子节点数组中
      if (map[parentId]) {
        map[parentId][childrenKey].push(map[id]);
      }
    }
  });

  return tree;
}



// 迭代树形结构的通用函数
export function traverseTree(treeList, callback,childKey = 'children') {
    // 执行回调方法
    treeList?.forEach(item => {
		callback(item)
		// 遍历子节点
		if (item[childKey] && item[childKey].length > 0) {
		   traverseTree(item[childKey], callback)
		}
	}) 
}
 